/*
 * CAutoAttackEvent.java
 *
 * Copyright (c) 2009 Giles Millward (Manigra). All rights reserved.
 *
 * This file is part of JRogueDPS.
 *
 * JRogueDPS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JRogueDPS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JRogueDPS.  If not, see <http://www.gnu.org/licenses/>.
 */
package dpssystem;

import dpssystem.CAttackChance.HitType;
import dpssystem.CProc.AttackType;
import java.util.ArrayList;

/**
 *
 * @author gmillward
 */
public class CAutoAttackEvent extends CEvent {

    private CWeapon m_weapon;

    CAutoAttackEvent(double p_eventTime, CWeapon p_weaponStats) {
        super(p_eventTime);
        m_weapon = p_weaponStats;
    }

    public ArrayList<CEvent> runEvent(CSim p_sim) {
        ArrayList<CEvent> l_newEventList = new ArrayList<CEvent>();
        l_newEventList.add(new CAutoAttackEvent(p_sim.m_currentRunTime +
                    (m_weapon.m_weaponSpeed * p_sim.m_haste.getHaste()),
                    m_weapon));
        attackMob(p_sim);
        return l_newEventList;
    }

    private void attackMob(CSim p_sim) {
        double l_damage = 0;
        double l_avgDamage = m_weapon.m_avgDamage; // (min + max) / 2.0
        double l_handModifier = m_weapon.m_handModifier;
        double l_powerDamage = p_sim.m_baseStats.getAttackPower() / 14;
 

        l_damage = ((l_avgDamage / m_weapon.m_weaponSpeed) + (l_powerDamage)) * (m_weapon.m_weaponSpeed) * l_handModifier;

        CAttackChance.HitType l_hitType =
                p_sim.m_attackChance.getWhiteAttackType(p_sim.m_baseStats.getHitChance(),
                                                            p_sim.m_baseStats.getExpertiseDodge(),
                                                            p_sim.m_baseStats.getCritChance() -
                                                            0.0479); // White attack crit depression of 4.79%
        if (l_hitType == CAttackChance.HitType.GLANCING) {
            l_damage = l_damage * 0.75;
            m_weapon.m_poison.procPoison(false);
        } else if (l_hitType == CAttackChance.HitType.CRIT) {
            l_damage = l_damage * 2.00;
            m_weapon.m_poison.procPoison(false);            
            p_sim.m_player.m_energyRegen.focusedAttacks();
        } else if (l_hitType == CAttackChance.HitType.NORMAL) {
            m_weapon.m_poison.procPoison(false);
        } else if (l_hitType == CAttackChance.HitType.DODGE) {
            l_damage = 0;
        } else if (l_hitType == CAttackChance.HitType.MISS) {
            l_damage = 0;
        } else {
            l_damage = 0;
        }

        // Remove armor pen mitigation
        l_damage -= p_sim.m_arpReduction.getDamageReduction(l_damage, m_weapon.m_isMace);

        m_weapon.m_autoAttackStats.addStats(l_hitType, l_damage);

        // Do enchant procs for white attack
        boolean l_procTypeEnchant = false;
        if (this.m_weapon.m_enchantProc != null)
        {
            l_procTypeEnchant = true;
        }

        if (l_hitType == HitType.NORMAL || l_hitType == HitType.GLANCING)
        {
            p_sim.m_trinketManager.executeProc(p_sim, AttackType.MeleeWhite, false, m_weapon);
            if (l_procTypeEnchant)
            {
                this.m_weapon.m_enchantProc.executeProc(p_sim, AttackType.MeleeWhite, false, m_weapon);
            }
        } else if (l_hitType == HitType.CRIT)
        {
            p_sim.m_trinketManager.executeProc(p_sim, AttackType.MeleeWhite, true, m_weapon);
            if (l_procTypeEnchant)
            {
                this.m_weapon.m_enchantProc.executeProc(p_sim, AttackType.MeleeWhite, true, m_weapon);
            }
        }

        // Sword proc specialisation
        if (this.m_weapon.m_isSword)
        {
            if (p_sim.m_dpsInterface.m_talents.getSwordSpecialization() != 0)
            {
                if (p_sim.m_rng.nextDouble() <= p_sim.m_dpsInterface.m_talents.getSwordSpecializationDouble())
                {
                    this.attackMob(p_sim);
                }
            }
        }
        
        return;
    }
}
